*&---------------------------------------------------------------------*
*& Report ZEX_LISTING_211                                              *
*&---------------------------------------------------------------------*
*& Created By: James Wood (james.wood@bowdarkconsulting.com)           *
*& Created On: 12/12/2008                                              *
*& Purpose:    This program demonstrates the simple math API shown in  *
*&             Listing 2.11. There are several things to bear in mind  *
*&             with an example like this. First, an API like this      *
*&             would normally be implemented with class methods.       *
*&             Secondly, such methods would normally be functional     *
*&             methods that can be used in expressions. You will see   *
*&             this demonstrated in other APIs as you work on more     *
*&             complex examples in later chapters. For now, we are     *
*&             just demonstrating class creation, method calls, etc.   *
*&---------------------------------------------------------------------*
REPORT zex_listing_211.

*----------------------------------------------------------------------*
*       CLASS lcl_math DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_math DEFINITION.

  PUBLIC SECTION.
    METHODS:
      max   IMPORTING value(a) TYPE i
                      value(b) TYPE i
            EXPORTING value(result) TYPE i,

      round CHANGING  a TYPE f,

      log   IMPORTING x TYPE f
                      b TYPE i OPTIONAL
            EXPORTING y TYPE f,

      power IMPORTING base TYPE f
                      exponent TYPE f DEFAULT 2
            RETURNING value(result) TYPE f.

ENDCLASS.                    "lcl_math DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_math IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_math IMPLEMENTATION.

  METHOD max.
    IF a > b.
      result = a.
    ELSE.
      result = b.
    ENDIF.
  ENDMETHOD.                    "max

  METHOD round.
*   Method-Local Data Declarations:
    DATA: lv_ipart TYPE f,
          lv_fpart TYPE f.

*   Determine the integer and fractional parts of the input:
    lv_ipart = TRUNC( a ).
    lv_fpart = FRAC( a ).

*   Round accordingly:
    IF lv_fpart GT '0.5'.
      a = lv_ipart + 1.
    ELSE.
      a = lv_ipart.
    ENDIF.
  ENDMETHOD.                    "round

  METHOD log.
*   The logarithm function provided out of the box with ABAP
*   only works with base-10 logarithms. Therefore, the following
*   division operation will change the base of the result to the
*   selected value of import parameter b.
    y = LOG10( x ) / LOG10( b ).
  ENDMETHOD.                    "log

  METHOD power.
    result = base ** exponent.
  ENDMETHOD.                    "power

ENDCLASS.                    "lcl_math IMPLEMENTATION

*&---------------------------------------------------------------------*
*& START-OF-SELECTION Event                                            *
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM test_math_class.

*&---------------------------------------------------------------------*
*&      Form  test_math_class
*&---------------------------------------------------------------------*
FORM test_math_class.
* Local Data Declarations:
  DATA: lr_math_api TYPE REF TO lcl_math,
        lv_a        TYPE i VALUE 10,
        lv_b        TYPE i VALUE 20,
        lv_c        TYPE i,
        lv_pi       TYPE f VALUE '3.14159',
        lv_log      TYPE f,
        lv_power    TYPE f.

* Create an instance of the math API:
  CREATE OBJECT lr_math_api.

* Test the max method:
  CALL METHOD lr_math_api->max
    EXPORTING
      a      = lv_a
      b      = lv_b
    IMPORTING
      RESULT = lv_c.

  WRITE: / 'Max is:', lv_c.

* Test the round method:
  CALL METHOD lr_math_api->round
    CHANGING
      a = lv_pi.

  WRITE: / 'Rounded value is:', lv_pi EXPONENT 0 DECIMALS 2.

* Test the logarithm method:
  CALL METHOD lr_math_api->log
    EXPORTING
      x = '8.00'
      b = 2
    IMPORTING
      y = lv_log.

  WRITE: / 'Logarithm value is:', lv_log EXPONENT 0 DECIMALS 2.

* Test the power method:
  CALL METHOD lr_math_api->power
    EXPORTING
      base     = '2.00'
      exponent = '4.00'
    RECEIVING
      result   = lv_power.

  WRITE: / 'Exponential result is:', lv_power EXPONENT 0 DECIMALS 2.

ENDFORM.                    "test_math_class